package user

import (
	"disk/service/user/dao"
	"disk/service/user/utils"
	"disk/service/utils/token"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"time"
)

type LoginForm struct {
	Name     string
	Password string
}

func Login(r *gin.RouterGroup) {
	r.POST("/login", func(c *gin.Context) {
		var loginForm LoginForm
		if err := c.ShouldBind(&loginForm); err != nil {
			c.JSON(200, gin.H{
				"msg":  "数据校验未通过",
				"data": err.Error(),
				"code": 400,
			})
		} else {
			userDataList := dao.GetUserByName(loginForm.Name)
			if len(userDataList) == 0 {
				c.JSON(200, gin.H{
					"msg":  "用户不存在",
					"data": loginForm.Name,
					"code": 400,
				})
			} else {
				if time.Now().Before(userDataList[0].LockedUntil) {
					timeTemplate := "2006-01-02 15:04:05"
					c.JSON(200, gin.H{
						"msg":  "账户已被锁定到" + userDataList[0].LockedUntil.Format(timeTemplate),
						"data": loginForm.Name,
						"code": 400,
					})
				} else {
					// 对从前端传来的加密密码进行解码，再进行加盐哈希，与存储的加盐哈希进行对比
					rawPassword, _ := utils.RsaDecode(loginForm.Password)
					loginPassword := utils.GetHash(rawPassword)
					if userDataList[0].Password == loginPassword {
						dao.RecordPasswordWrong(userDataList[0], 0)
						dao.SetUserStatus(userDataList[0], "in")
						// 签发token
						tokenDuration := time.Duration(viper.GetInt("token.shortDuration"))
						longDuration := time.Duration(viper.GetInt("token.longDuration"))
						signature, _ := token.IssueRS(loginForm.Name, time.Now().Add(time.Minute*tokenDuration))
						// token 不放在返回体中，而是放到 HTTP 响应头里（前端从 Header 读取）
						c.Header("new_token", signature)
						signatureLong, _ := token.IssueRS(loginForm.Name, time.Now().Add(time.Minute*longDuration))
						c.Header("new_long_token", signatureLong)
						c.Header("name", loginForm.Name)
						c.JSON(200, gin.H{
							"msg":  "登录成功",
							"data": loginForm.Name,
							"code": 200,
						})
					} else {
						dao.RecordPasswordWrong(userDataList[0], userDataList[0].PasswordTry+1)
						c.JSON(200, gin.H{
							"msg":  "密码错误",
							"data": loginForm.Name,
							"code": 400,
						})
					}
				}
			}
		}
	})
}
